﻿namespace Snipps.ViewModels.Pages
{
    using System.Windows.Input;

    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;

    using Snipps.Core;
    using Snipps.Core.Entities;
    using Snipps.Infrastructure;
    using Snipps.Langs;
    using Snipps.Messages;
    using Snipps.Validators;

    public class EditTagViewModel : ValidatableViewModelBase, IPageViewModel
    {
        private readonly ActiveViewModel _cancelButtonActive;

        private readonly EditTagValidator _editTagValidator;

        private readonly ActiveViewModel _saveButtonActive;

        private readonly ISnippetsDataContext _snippetsDataContext;

        private Tag _editedTag;

        private bool _isActive;

        private string _tagName;

        private bool _tagNameIsActive;

        public EditTagViewModel(ISnippetsDataContext snippetsDataContext)
        {
            _snippetsDataContext = snippetsDataContext;

            _editTagValidator = new EditTagValidator(IsTagExists);
            _saveButtonActive = new ActiveViewModel();
            _cancelButtonActive = new ActiveViewModel();
            SaveCommand = new RelayCommand(OnSave, () => !HasErrors);
            CancelCommand = new RelayCommand(OnCancel);
        }

        public ICommand SaveCommand { get; private set; }

        public ICommand CancelCommand { get; private set; }

        public ActiveViewModel SaveButtonActive
        {
            get
            {
                return _saveButtonActive;
            }
        }

        public ActiveViewModel CancelButtonActive
        {
            get
            {
                return _cancelButtonActive;
            }
        }

        public Tag EditedTag
        {
            get
            {
                return _editedTag;
            }

            set
            {
                SetProperty(ref _editedTag, value, "EditedTag", OnEditedTagChanged);
            }
        }

        public string TagName
        {
            get
            {
                return _tagName;
            }

            set
            {
                SetProperty(ref _tagName, value, "TagName");
            }
        }

        public bool TagNameIsActive
        {
            get
            {
                return _tagNameIsActive;
            }

            set
            {
                SetProperty(ref _tagNameIsActive, value, "TagNameIsActive");
            }
        }

        public string Name
        {
            get
            {
                return Lang.EditTagViewName;
            }
        }

        public bool IsActive
        {
            get
            {
                return _isActive;
            }

            set
            {
                SetProperty(ref _isActive, value, "IsActive", OnIsActiveChanged);
            }
        }

        private bool IsTagExists(string tagName)
        {
            var tag = _snippetsDataContext.GetTag(tagName);

            if (tag == null)
            {
                return false;
            }

            return !tag.Equals(EditedTag);
        }

        public override void Cleanup()
        {
            base.Cleanup();
            _tagName = string.Empty;
        }

        private void OnIsActiveChanged()
        {
            if (IsActive)
            {
                _cancelButtonActive.IsActive = false;
                _saveButtonActive.IsActive = false;

                TagNameIsActive = true;
                OnEditedTagChanged();
            }
            else
            {
                Cleanup();
            }
        }

        private void OnCancel()
        {
            RemoveAllErrors();
            Messenger.Default.Send(new CancelMsg());
        }

        private void OnSave()
        {
            Validate(_editTagValidator);

            if (HasErrors)
            {
                return;
            }

            EditedTag.Name = TagName;
            _snippetsDataContext.SaveTag(EditedTag);
            Messenger.Default.Send(new ItemChangedMsg { Item = EditedTag });

            EditedTag = null;
        }

        private void OnEditedTagChanged()
        {
            if (EditedTag != null)
            {
                TagName = EditedTag.Name;
            }
        }
    }
}